package org.wattdepot.cli.command;

import java.util.List;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.source.jaxb.Source;

/**
 * Returns a string containing a breakdown of the types of fuel used by the specified
 * source. If the source is a virtual source, it returns data on all nonvirtual subsources
 * of the given source.
 * 
 * @author Kendyll Doi
 * @author Kimberly Heu
 *
 */
public class WattFuelTypes {

  /**
   * Returns a String containing information on the types of fuel used by the given source.
   * 
   * @param sourceString The source to find information for.
   * @param client The WattDepotClient to use.
   * @return The information on fuel types used.
   */
  public static String wattFuelTypes (String sourceString, WattDepotClient client) {
    // Messages to be displayed in the case of an error
    String resourceNotFoundMessage = "No data found for ";
    String miscClientMessage = "Error while retrieving resource";
    String notAuthorizedMessage = "Not authorized to retrieve information.";
    String badXmlMessage = "Error enountered getting information from server.";
    
    StringBuffer buf = new StringBuffer(2000); // Buffer to contain contents to return
    String output = ""; // String to return
    
    try {
      Source source = client.getSource(sourceString); // Get the Source to look up information on
      
      if (source.isVirtual()) {
        // If it is virutal, then need to traverse structure to get all subsources
        
        // Call the getSubsourcesFuel method with the given source and client, and each of the
        // possible types of fuels used
        List<String> wasteSources = WattSubsourcesFuel.getSubsourcesFuel(source, "waste", client);
        List<String> coalSources = WattSubsourcesFuel.getSubsourcesFuel(source, "coal", client);
        List<String> lsfoSources = WattSubsourcesFuel.getSubsourcesFuel(source, "LSFO", client);
        

        // If there were plants using waste, print them
        if (!wasteSources.isEmpty()) {
          buf.append("Waste: ");
          for (String subSource : wasteSources) {
            buf.append(subSource);
            buf.append(", ");
          }
          buf.append('\n');
        }

        // If there were plants using coal, print them
        if (!coalSources.isEmpty()) {
          buf.append("Coal: ");
          for (String subSource : coalSources) {
            buf.append(subSource);
            buf.append(", ");
          }
          buf.append('\n');
        }
        
        // If there were plants using LSFO, print them
        if (!lsfoSources.isEmpty()) {
          buf.append("LSFO: ");
          for (String subSource : lsfoSources) {
            buf.append(subSource);
            buf.append(", ");
          }
          buf.append('\n');
        }
      }
      else {
        // Nonvirtual source, has fuelType set as a property
        String fuelType = source.getProperty("fuelType");
        buf.append(fuelType);
        buf.append(": ");
        buf.append(sourceString);
      }
      
    }
    catch (ResourceNotFoundException e) {
      // Occurs if source does not exist
      buf.append(resourceNotFoundMessage);
      buf.append(sourceString);
    }
    catch (MiscClientException e) {
      // Occurs if error happens while getting data
      buf.append(miscClientMessage);
    }
    catch (NotAuthorizedException e) {
      // Occurs if user is not authorized to get information
      buf.append(notAuthorizedMessage);
    }
    catch (BadXmlException e) {
      // Occurs if data is corrupted
      buf.append(badXmlMessage);
    }
    catch (Exception e) {
      buf.append("Encountered error: ");
      buf.append(e);
      e.printStackTrace();
    }
    
    // Convert buffer to String and return
    output = buf.toString();
    return output;
  }
}
